home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
mint
/
mint110s.zoo
/
tosfs.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-02-02
|
36KB
|
1,528 lines
/*
Copyright 1991,1992 Eric R. Smith.
Copyright 1992,1993,1994 Atari Corporation.
All rights reserved.
*/
/* a VERY simple tosfs.c
* this one is extremely brain-damaged, but will serve OK for a
* skeleton in which to put a "real" tosfs.c
*/
#include "mint.h"
/* if NEWWAY is defined, tosfs uses the new dup_cookie/release_cookie
* protocol to keep track of file cookies, instead of the old
* method of "timing"
*/
/* #define NEWWAY */
#if 0
#define COOKIE_DB(x) DEBUG(x)
#else
#define COOKIE_DB(x)
#endif
/* if RO_FASCISM is defined, the read/write modes are enforced. This is
* a Good Thing, not fascist at all. Ask Allan Pratt why he chose
* that name sometime.
*/
#define RO_FASCISM
/* temporary code for debugging Falcon media change bug */
#if 0
#define MEDIA_DB(x) DEBUG(x)
#else
#define MEDIA_DB(x)
#endif
/* search mask for anything OTHER THAN a volume label */
#define FILEORDIR 0x37
char tmpbuf[PATH_MAX+1];
static long ARGS_ON_STACK tos_root P_((int drv, fcookie *fc));
static long ARGS_ON_STACK tos_lookup P_((fcookie *dir, const char *name, fcookie *fc));
static long ARGS_ON_STACK tos_getxattr P_((fcookie *fc, XATTR *xattr));
static long ARGS_ON_STACK tos_chattr P_((fcookie *fc, int attrib));
static long ARGS_ON_STACK tos_chown P_((fcookie *fc, int uid, int gid));
static long ARGS_ON_STACK tos_chmode P_((fcookie *fc, unsigned mode));
static long ARGS_ON_STACK tos_mkdir P_((fcookie *dir, const char *name, unsigned mode));
static long ARGS_ON_STACK tos_rmdir P_((fcookie *dir, const char *name));
static long ARGS_ON_STACK tos_remove P_((fcookie *dir, const char *name));
static long ARGS_ON_STACK tos_getname P_((fcookie *root, fcookie *dir,
char *pathname, int size));
static long ARGS_ON_STACK tos_rename P_((fcookie *olddir, char *oldname,
fcookie *newdir, const char *newname));
static long ARGS_ON_STACK tos_opendir P_((DIR *dirh, int flags));
static long ARGS_ON_STACK tos_readdir P_((DIR *dirh, char *nm, int nmlen, fcookie *));
static long ARGS_ON_STACK tos_rewinddir P_((DIR *dirh));
static long ARGS_ON_STACK tos_closedir P_((DIR *dirh));
static long ARGS_ON_STACK tos_pathconf P_((fcookie *dir, int which));
static long ARGS_ON_STACK tos_dfree P_((fcookie *dir, long *buf));
static long ARGS_ON_STACK tos_writelabel P_((fcookie *dir, const char *name));
static long ARGS_ON_STACK tos_readlabel P_((fcookie *dir, char *name, int namelen));
static long ARGS_ON_STACK tos_creat P_((fcookie *dir, const char *name, unsigned mode,
int attrib, fcookie *fc));
static DEVDRV * ARGS_ON_STACK tos_getdev P_((fcookie *fc, long *devsp));
static long ARGS_ON_STACK tos_open P_((FILEPTR *f));
static long ARGS_ON_STACK tos_write P_((FILEPTR *f, const char *buf, long bytes));
static long ARGS_ON_STACK tos_read P_((FILEPTR *f, char *buf, long bytes));
static long ARGS_ON_STACK tos_lseek P_((FILEPTR *f, long where, int whence));
static long ARGS_ON_STACK tos_ioctl P_((FILEPTR *f, int mode, void *buf));
static long ARGS_ON_STACK tos_datime P_((FILEPTR *f, short *time, int rwflag));
static long ARGS_ON_STACK tos_close P_((FILEPTR *f, int pid));
static long ARGS_ON_STACK tos_dskchng P_((int drv));
#ifdef NEWWAY
static long ARGS_ON_STACK tos_release P_((fcookie *fc));
static long ARGS_ON_STACK tos_dupcookie P_((fcookie *dst, fcookie *src));
#endif
/* some routines from biosfs.c */
extern long ARGS_ON_STACK null_select P_((FILEPTR *f, long p, int mode));
extern void ARGS_ON_STACK null_unselect P_((FILEPTR *f, long p, int mode));
DEVDRV tos_device = {
tos_open, tos_write, tos_read, tos_lseek, tos_ioctl, tos_datime,
tos_close, null_select, null_unselect
};
FILESYS tos_filesys = {
(FILESYS *)0,
FS_KNOPARSE | FS_NOXBIT | FS_LONGPATH,
tos_root,
tos_lookup, tos_creat, tos_getdev, tos_getxattr,
tos_chattr, tos_chown, tos_chmode,
tos_mkdir, tos_rmdir, tos_remove, tos_getname, tos_rename,
tos_opendir, tos_readdir, tos_rewinddir, tos_closedir,
tos_pathconf, tos_dfree, tos_writelabel, tos_readlabel,
nosymlink, noreadlink, nohardlink, nofscntl, tos_dskchng,
#ifdef NEWWAY
tos_release, tos_dupcookie
#else
0, 0
#endif
};
/* some utility functions and variables: see end of file */
static DTABUF *lastdta; /* last DTA buffer we asked TOS about */
static DTABUF foo;
static void do_setdta P_((DTABUF *dta));
static int executable_extension P_((char *));
/* this array keeps track of which drives have been changed */
/* a nonzero entry means that the corresponding drive has been changed,
* but GEMDOS doesn't know it yet
*/
static char drvchanged[NUM_DRIVES];
/* force TOS to see a media change */
static void force_mediach P_((int drv));
static long ARGS_ON_STACK Newgetbpb P_((int));
static long ARGS_ON_STACK Newmediach P_((int));
static long ARGS_ON_STACK Newrwabs P_((int, void *, int, int, int, long));
#ifdef NEWWAY
#define NUM_INDICES 64
#else
#define NUM_INDICES 128
#define MIN_AGE 8
#endif
struct tindex {
char *name; /* full path name */
FILEPTR *open; /* fileptrs for this file; OR
* count of number of open directories
*/
LOCK *locks; /* locks on this file */
/* file status */
long size;
short time;
short date;
short attr;
short valid; /* 1 if the above status is still valid */
#ifdef NEWWAY
short links; /* how many times index is in use */
#else
short stamp; /* age of this index, for garbage collection */
#endif
} gl_ti[NUM_INDICES];
/* temporary index for files found by readdir */
static struct tindex tmpindex;
static char tmpiname[PATH_MAX];
static struct tindex *tstrindex P_((char *s));
static int tfullpath P_((char *result, struct tindex *base, const char *name));
static struct tindex *garbage_collect P_((void));
#ifndef NEWWAY
static short tclock; /* #calls to tfullpath since last garbage
collection */
#endif
/* some extra flags for the attr field */
/*
* is a string the name of a file with executable extension?
*/
#define FA_EXEC 0x4000
/*
* should the file be deleted when it is closed?
*/
#define FA_DELETE 0x2000
/*
* NOTE: call executable_extension only on a DTA name returned from
* Fsfirst(), not on an arbitrary path, for two reasons: (1) it
* expects only upper case, and (2) it looks only for the 1st extension,
* so a folder with a '.' in its name would confuse it.
*/
static int
executable_extension(s)
char *s;
{
while (*s && *s != '.') s++;
if (!*s) return 0;
s++;
if (s[0] == 'T') {
return (s[1] == 'T' && s[2] == 'P') ||
(s[1] == 'O' && s[2] == 'S');
}
if (s[0] == 'P')
return s[1] == 'R' && s[2] == 'G';
if (s[0] == 'A')
return s[1] == 'P' && s[2] == 'P';
if (s[0] == 'G')
return s[1] == 'T' && s[2] == 'P';
return 0;
}
/*
* Look in the table of tos indices to see if an index corresponding
* to this file name already exists. If so, mark it as being used
* and return it. If not, find an empty slot and make an index for
* this string. If no empty slots exist, garbage collect and
* try again.
*
* This routine is pretty dumb; we really should use a hash table
* of some sort
*/
static struct tindex *tstrindex(s)
char *s;
{
int i;
char *r;
struct tindex *t, *free = 0;
assert(s != 0);
t = gl_ti;
for (i = 0; i < NUM_INDICES; i++, t++) {
if (t->name && !stricmp(t->name, s)) {
#ifndef NEWWAY
t->stamp = tclock; /* update use time */
#endif
return t;
}
else if (!t->name && !free)
free = t;
}
if (!free) {
free = garbage_collect();
}
#ifdef NEWWAY
if (!free) {
FORCE("tosfs: all slots in use!!");
FORCE("Links\tName");
t = gl_ti;
for (i = 0; i < NUM_INDICES; i++,t++) {
FORCE("%d\t%s", t->links, t->name);
}
FATAL("tosfs: unable to get a file name index");
}
#else
if (!free) {
FATAL("tosfs: unable to get a file name index");
}
#endif
r = kmalloc((long)strlen(s)+1);
if (!r) {
FATAL("tosfs: unable to allocate space for a file name");
}
strcpy(r, s);
free->name = r;
#ifdef NEWWAY
free->links = 0;
#else
free->stamp = tclock;
#endif
free-